package com.miyake.dsp.osa.lab.wrapper;

import com.miyake.dsp.ComplexArray;
import com.miyake.dsp.common.CommonTool;
import com.miyake.dsp.filter.FilterImplScilabProxy;
import com.miyake.dsp.filter.FilterSetting;
import com.miyake.dsp.filter.FilterSetting.FilterAlgo;
import com.miyake.dsp.filter.FilterSetting.FilterType;
import com.miyake.dsp.osa.lab.Calculator;
import com.miyake.dsp.osa.lab.LabUiAnnotation;
import com.miyake.dsp.otdr.OtdrRxExSetting;
@LabUiAnnotation(caption="OTDR Simulator Rx Ex")
public class OtdrSimulatorRxExWrapper extends Calculator {
	//public static final String INPUT_DISTANCE = "Distance";
	public static final String INPUT_FREQUENCY = "Sampling Frequency";
	public static final String INPUT_LOSS = "Loss";
	public static final String OUT_0DB = "00dB";
	public static final String OUT_3DB = "03dB";
	public static final String OUT_6DB = "06dB";
	public static final String OUT_9DB = "09dB";
	public static final String OUT_12DB = "12dB";
	public static final String OUT_15DB = "15dB";
	public static final String OUT_18DB = "18dB";
	public static final String OUT_21DB = "21dB";
	private OtdrRxExSetting setting;
	public OtdrSimulatorRxExWrapper(OtdrRxExSetting setting) {
		this.setting = setting;
		initInput(INPUT_FREQUENCY);
		initInput(INPUT_LOSS);
		initOutput(OUT_0DB);
		initOutput(OUT_3DB);
		initOutput(OUT_6DB);
		initOutput(OUT_9DB);
		initOutput(OUT_12DB);
		initOutput(OUT_15DB);
		initOutput(OUT_18DB);
		initOutput(OUT_21DB);
	}
	
	@Override
	public synchronized void process() {
		double[] in = this.getInput(INPUT_LOSS).getRealPart();
		double ceiling = setting.getCeiling();
		double noiseLevel = setting.getNoise();
		double[] noise = CommonTool.getWhiteNoise(in.length, noiseLevel, 0);
		double samplingFrequency;
		if (getInput(INPUT_FREQUENCY) != null) {
			samplingFrequency = getInput(INPUT_FREQUENCY).getRealPart()[0];
		}
		else {
			samplingFrequency = setting.getSamplingFrequency();
		}
		String key;
		
		FilterSetting filterSetting = new FilterSetting();
		FilterImplScilabProxy filter = new FilterImplScilabProxy(filterSetting);
		filterSetting.setFilterAlgo(FilterAlgo.Butterworth);
		filterSetting.setFilterType(FilterType.Lowpass);
		filterSetting.setOrder(1);
		filterSetting.setFrequency(samplingFrequency);
		
		for (int att = 0; att <= 21; att += 3) {
			double[] out = CommonTool.getGained(in, (double)att * -1.0);
			out = CommonTool.getMixed(out, noise);
			key = getAttString(att) + "dB";
			filterSetting.setCutoff1(getBandwidth(att));
			filter.setSource(new ComplexArray(out));
			out = filter.getProcessed().getRealPart();
			out = CommonTool.getLimited(out, ceiling);
			this.setOutput(key, out);
			
		}
	}

	private double getBandwidth(int att) {
		if (att == 0) {
			return setting.getBandwidth00dB();
		}
		else if (att == 3) {
			return setting.getBandwidth03dB();
		}
		else if (att == 6) {
			return setting.getBandwidth06dB();
		}
		else if (att == 9) {
			return setting.getBandwidth09dB();
		}
		else if (att == 12) {
			return setting.getBandwidth12dB();
		}
		else if (att == 15) {
			return setting.getBandwidth15dB();
		}
		else if (att == 18) {
			return setting.getBandwidth18dB();
		}
		else if (att == 21) {
			return setting.getBandwidth21dB();
		}
		return 0;
	}

	private String getAttString(int att) {
		if (att > 9) {
			return String.valueOf(att);
		}
		return "0" + String.valueOf(att);
	}

	@Override
	public Object getSetting() {
		return setting;
	}

}
